#ifndef SERVER_H
#define SERVER_H


#include <my_header.h>
#include <mysql/mysql.h>
#include <shadow.h>


#define LOG_WRITE(msg)  {                                                  \
    int fd = open("/var/log/syslog", O_WRONLY | O_APPEND | O_CREAT, 0666); \
    time_t now = time(NULL);                                               \
    time(&now);                                                            \
    struct tm* localTime = localtime(&now);                                \
    char message[4096] = {0};                                              \
    sprintf(message, "[%d-%d-%d][%d:%d:%d]: %s\n", localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec, msg);\
    write(fd, message, strlen(message));                                   \
    close(fd);                                                             \
} 

#define QUERY_CHECK(retval, mysql)                                 \
do {                                                               \
    if (retval) {                                                  \
        fprintf(stderr, "mysql_query: %s\n",mysql_error((mysql))); \
        return (-1);                                               \
   }                                                               \
} while (0)


/* 私有传输协议 */
typedef struct train_s {
    int length;
    char data[1000];
} train_t;


/* 登录信息 */
typedef struct user_s{
    char userName[128];
    char passwd[1024];
} user_t;


/* 任务队列 */
typedef struct node_s {
    int netFd;
    struct node_s *next;
} node_t;
typedef struct taskQueue_s {
    int queueSize;
    node_t *front;
    node_t *rear;
} taskQueue_t;



/* 所有共享资源 */
typedef struct threadPool_s {
    int workerNum;                // 线程数量
    pthread_t *workerArr;         // 所有的线程 ID
    taskQueue_t taskQueue;        // 任务队列
    int epollFd;                  // epoll 文件
    char pathBuffer[256][256];    // 当前路径的缓存
    char userBuffer[128][128];    // 当前用户名的缓存
    char home[128];               // 家目录
    pthread_mutex_t mutex;        // 锁
    pthread_cond_t cond;          // 条件变量
} threadPool_t;


/* threadpool.c */
int initThreadPool(threadPool_t *pThreadPool, int workerNum); // 初始化线程池
int initTaskQueue(taskQueue_t *pTaskQueue);                   // 初始化任务队列 
int enQueue(taskQueue_t *pTaskQueue, int netfd);              // 入队
int deQueue(taskQueue_t *pTaskQueue);                         // 出队


/* worker.c */
int makeWorkers(threadPool_t *pThreadPool); // 启动所有线程
void *threadFunc(void *arg);                // 回调函数


/* sendrecv.c */
int sendMessageToClient(int fd, char *buf, int sendLength);      // 发消息
int sendFileToClient(int fd, char *localPath, char *clientPath); // 发文件
ssize_t recvStdin(char *buf, int bufLength);                     // 收标准输入
ssize_t recvMessageFromClient(int fd, char *buf, int bufLength); // 收消息
int recvFileFromClient(int fd, MYSQL *mysql, threadPool_t *pThreadPool, int pid, char *virtualPath);       // 收文件


/* tcpepoll.c */
int tcpServerInit(char *ip, char *port, int *pSocketFd);             // listen
int acceptConnection(int socketFd, struct sockaddr_in *pClientAddr); // accept
int epollAdd(int epfd, int fd);                                      // 添加监听
int epollDelete(int epfd, int fd);                                   // 删除监听


/* directory.c */
void cutPath(const char *path, char (*dirs)[128]);     // 把"path1/path2/path3"类型的地址切割成 path1 path2 path3放入字符串数组

/* command.c */
void cutCmd(char *input,char *cmd,char *path1,char *path2);
int cutTail(char *path, char *left, char *right);
int checkCmd(char *cmd);
int changeDir_1(MYSQL* mysql,const char* username,char* curr_path,const char* dest_path);
int changeDir(MYSQL* mysql,const char* username,char* curr_path,const char* dest_path);
int listSearch(MYSQL* mysql,const char* username,const char* curr_path,char* list);
int changePath_1(MYSQL* mysql,const char* username,char* curr_path,const char* dest_path);
int changePath(MYSQL* mysql,const char* username,char* curr_path,const char* dest_path);


/* mysql.c */
void insertFile(char *filename,char *filepath,int filesize,char *filemd5,char *user, int parent, MYSQL *mysql);
int searchMd5(char *md5,MYSQL *mysql, char *size);
int getId(char *username, char *path, int *pid, MYSQL *mysql);
int searchFile(char *path, MYSQL *mysql, char *user, char *md5, char *home);
int mkDir(MYSQL *mysql,char* username,char* curr_path,char *dirpath);
int rmDir(MYSQL *mysql,char* username,char* curr_path,char *dirpath);
int removeFile(MYSQL *mysql,const char* username,char* curr_path,char *filepath);
int insertRoot(MYSQL *mysql, char *userName);
int  delToMk(MYSQL *mysql,const char* username,char* curr_path,char *filepath);

/* login.c */
int loading(user_t tmpuser, MYSQL *mysql);
int registration(user_t tmpuser, MYSQL *mysql);

#endif
